package cn.fx.baseweb.config;

import cn.fx.framework.redis.MyKeyGenerator;
import cn.fx.framework.redis.MyRedisCacheManager;
import cn.fx.framework.redis.MyRedisTemplate;
import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * 初始化Redis相关内容：
 * 缓存默认前缀、过期时间、cache初始化程序、redisTemplate、myRedisTemplate、myRedisCacheManager。
 * @author ljh
 * @since 2018-11-10 9:40
 **/
@Configuration
@EnableCaching
@Order(2)
public class MyRedisConfiguration {
    /**
     * RedisConnectionFactory由spring cache注入
     */
    private final RedisConnectionFactory redisConnectionFactory;

    @Autowired
    public MyRedisConfiguration(RedisConnectionFactory redisConnectionFactory) {
        this.redisConnectionFactory = redisConnectionFactory;
    }

    @Value("${site.redis.default-cache-prefix-keys-with:cache}")
    private String defaultPrefixKeysWith;

    @Value("${site.redis.default-entry-ttl-minutes:0}")
    private int defaultCacheEntryTTL;

    @Value("${site.redis.cache-initial-handler}")
    private String cacheInitialHandler;

    @Bean("redisTemplate")
    @Primary
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // set key serializer
        StringRedisSerializer serializer = MyRedisCacheManager.STRING_SERIALIZER;
        // 设置key序列化类，否则key前面会多了一些乱码
        template.setKeySerializer(serializer);
        template.setHashKeySerializer(serializer);

        // fastjson serializer
        GenericFastJsonRedisSerializer fastSerializer = MyRedisCacheManager.FASTJSON_SERIALIZER;
        template.setValueSerializer(fastSerializer);
        template.setHashValueSerializer(fastSerializer);
        // factory
        template.setConnectionFactory(redisConnectionFactory);
        template.afterPropertiesSet();
        return template;
    }

    @Bean(name="myKey")
    public KeyGenerator keyGenerator() {
        return new MyKeyGenerator();
    }

    @Bean(name = "myRedisCacheManager")
    @ConditionalOnMissingBean(MyRedisCacheManager.class)
    public MyRedisCacheManager cacheManager() {
        return MyRedisCacheManager.buildCacheManager(redisConnectionFactory,
                defaultPrefixKeysWith,defaultCacheEntryTTL,cacheInitialHandler);
    }

    @Bean("myRedisTemplate")
    @ConditionalOnMissingBean(MyRedisTemplate.class)
    public MyRedisTemplate myRedisTemplateBeanCreated(){
        return new MyRedisTemplate(defaultPrefixKeysWith,redisTemplate(),cacheManager());
    }
}
